package rules

import (
	"ddl_checker/internal/config"
	"regexp"
	"strings"
)

// PerformanceValidator 性能检查器 - 检查DDL中的性能问题
type PerformanceValidator struct {
	*BaseAPIChecker
}

// NewPerformanceValidator 创建性能检查器
func NewPerformanceValidator() *PerformanceValidator {
	config := APICheckerConfig{
		Enabled:  config.GetBool("PERFORMANCE_VALIDATOR_ENABLED", false),
		Timeout:  10,
		Endpoint: "",
		ApiKey:   "",
	}
	return &PerformanceValidator{
		BaseAPIChecker: NewBaseAPIChecker("性能检查器", config),
	}
}

// NewPerformanceValidatorEnabled 创建带启用状态的性能检查器
func NewPerformanceValidatorEnabled(enabled bool) *PerformanceValidator {
	config := APICheckerConfig{
		Enabled:  enabled,
		Timeout:  10,
		Endpoint: "",
		ApiKey:   "",
	}
	return &PerformanceValidator{
		BaseAPIChecker: NewBaseAPIChecker("性能检查器", config),
	}
}

// NewPerformanceValidatorWithConfig 创建带配置的性能检查器
func NewPerformanceValidatorWithConfig(config ValidatorConfig) *PerformanceValidator {
	checkerConfig := APICheckerConfig{
		Enabled: config.Enabled,
		Timeout: 10,
	}

	// 从设置中读取超时时间
	if timeout, ok := config.Settings["timeout"].(float64); ok {
		checkerConfig.Timeout = int(timeout)
	}

	return &PerformanceValidator{
		BaseAPIChecker: NewBaseAPICheckerWithSettings("性能检查器", checkerConfig, config.Settings),
	}
}

// Validate 执行性能检查
func (v *PerformanceValidator) Validate(data DDLCheckData) APIResult {
	result := APIResult{
		Conclusion: APIConclusionPass,
		Details:    []string{"### 性能检查"},
	}

	if strings.TrimSpace(data.Script) == "" {
		result.Conclusion = APIConclusionFail
		result.Details = append(result.Details, "❌ 未提供DDL脚本")
		return result
	}

	// 性能问题检测
	performanceIssues := v.detectPerformanceIssues(data.Script)

	if len(performanceIssues) == 0 {
		result.Details = append(result.Details, "✅ 性能检查通过")
	} else {
		warningCount := 0
		for _, issue := range performanceIssues {
			if issue.level == "high" {
				result.Conclusion = APIConclusionWarning
			} else {
				warningCount++
			}
			result.Details = append(result.Details, issue.message)
		}

		if result.Conclusion == APIConclusionPass && warningCount > 0 {
			result.Conclusion = APIConclusionWarning
		}
	}

	return result
}

// performanceIssue 性能问题
type performanceIssue struct {
	level   string // "high", "medium", "low"
	message string
}

// detectPerformanceIssues 检测性能问题
func (v *PerformanceValidator) detectPerformanceIssues(script string) []performanceIssue {
	var issues []performanceIssue

	// 检查所有模式
	allPatterns := map[string]performanceIssue{
		// 高优先级问题
		`(?i)\bCREATE\s+TABLE\s+\w+\s*\([^)]*\bTEXT\b[^)]*\bPRIMARY\s+KEY\b[^)]*\)`: {
			level:   "high",
			message: "在包含TEXT类型的表上创建主键可能严重影响性能",
		},
		`(?i)\bALTER\s+TABLE\s+\w+\s+ADD\s+COLUMN\s+\w+\s+TEXT\b`: {
			level:   "high",
			message: "向大表添加TEXT列可能造成表重建，性能影响较大",
		},
		`(?i)\bCREATE\s+INDEX\s+ON\s+\w+\s*\([^)]*\bVARCHAR\s*\(\s*255\s*\)[^)]*\)`: {
			level:   "medium",
			message: "在长VARCHAR列上创建索引可能影响性能，考虑使用前缀索引",
		},
		`(?i)\bCREATE\s+TABLE\s+\w+\s*\([^)]*\bFOREIGN\s+KEY\b[^)]*\)`: {
			level:   "medium",
			message: "外键约束可能影响插入和更新性能",
		},
		`(?i)\bCREATE\s+TABLE\s+\w+\s*\([^)]*\bCHECK\s+CONSTRAINT\b[^)]*\)`: {
			level:   "low",
			message: "检查约束可能影响DML操作性能",
		},
	}

	// 检查每个模式
	for pattern, issue := range allPatterns {
		re := regexp.MustCompile(pattern)
		if re.MatchString(script) {
			issues = append(issues, issue)
		}
	}

	// 检查多表操作
	if v.hasMultiTableOperations(script) {
		issues = append(issues, performanceIssue{
			level:   "medium",
			message: "检测到多表操作，可能影响性能",
		})
	}

	// 检查缺少索引
	if v.missingRecommendedIndex(script) {
		issues = append(issues, performanceIssue{
			level:   "low",
			message: "建议在常用查询条件列上创建索引",
		})
	}

	return issues
}

// hasMultiTableOperations 检查是否存在多表操作
func (v *PerformanceValidator) hasMultiTableOperations(script string) bool {
	joinPattern := `(?i)\bJOIN\b`
	unionPattern := `(?i)\bUNION\b`
	subqueryPattern := `(?i)\bSELECT\s+.*\bFROM\s+\(.*SELECT.*\)`

	reJoin := regexp.MustCompile(joinPattern)
	reUnion := regexp.MustCompile(unionPattern)
	reSubquery := regexp.MustCompile(subqueryPattern)

	return reJoin.MatchString(script) || reUnion.MatchString(script) || reSubquery.MatchString(script)
}

// missingRecommendedIndex 检查是否缺少推荐索引
func (v *PerformanceValidator) missingRecommendedIndex(script string) bool {
	// 检查是否有WHERE条件但没有对应索引
	hasWhere := regexp.MustCompile(`(?i)\bWHERE\s+\w+\s*=.*`).MatchString(script)
	hasCreateIndex := regexp.MustCompile(`(?i)\bCREATE\s+INDEX\b`).MatchString(script)

	return hasWhere && !hasCreateIndex
}
